package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.FocusUser;
import com.itheima.domain.mongo.Video;
import com.itheima.domain.vo.CommentVo;
import com.itheima.domain.vo.PageBeanVo;
import com.itheima.domain.vo.VideoVo;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.FocusUserService;
import com.itheima.service.mongo.VideoService;
import com.itheima.util.ConstantUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class VideoManager {

    @Reference
    private VideoService videoService;

    @Reference
    private UserInfoService userInfoService;

    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private FastFileStorageClient client;  //存储的客户端  注入会报错 , 不影响执行
    @Autowired
    private FdfsWebServer webServer; // tracker的服务器  注入会报错 , 不影响执行

    @Reference
    private FocusUserService focusUserService;

    @Autowired
    private MQVideoManager mqVideoManager;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    /**
     * 查询小视频列表
     * @param pageNumber
     * @param pageSize
     * @return
     */
    //@Cacheable(value = "video" ,key = "'video_'+#pageNumber+'_'+#pageSize")
    public PageBeanVo findVideo(Integer pageNumber, Integer pageSize) {

        //System.out.println("-------------------->分页代码执行");
        //1.获取当前用户id
        Long loginUserId = UserHolder.getId();
        //2.查询小视频列表
        PageBeanVo pageBeanVo = videoService.findVideoByUserId(pageNumber, pageSize, loginUserId);
        List<Video> items = (List<Video>) pageBeanVo.getItems();//可以设置假数据
        List<VideoVo> videoVoList = new ArrayList<>();
        //3.封装vo    item->videoList
        if (CollectionUtil.isNotEmpty(items)) {
            for (Video video : items) {
                //3.1查询到个人信息
                UserInfo userInfo = userInfoService.findById(video.getUserId());
                //3.2创建vo对象
                VideoVo videoVo = new VideoVo();
                //3.3封装userInfo userId封装不了
                BeanUtil.copyProperties(userInfo, videoVo);
                //videoVo.setUserId( userInfo.getId() ); //手动赋值 用户的id
                //3.4封装video
                BeanUtil.copyProperties(video,videoVo);
                videoVo.setCover(video.getPicUrl());//封面
                videoVo.setVideoUrl(video.getVideoUrl());//视频
                videoVo.setSignature(video.getText());//文本  标题
                //设置是否关注
                String key = StrUtil.format(ConstantUtil.FOCUS_USER , UserHolder.getId()  , video.getUserId() );
                if (stringRedisTemplate.hasKey(key)) {//关注过
                    videoVo.setHasFocus(1);
                }
                //判断    该视频是否被点过赞   xx对哪个视频进行了点赞操作  缓存是否有这条数据
                String key2 = StrUtil.format(ConstantUtil.VIDEO_LIKE, UserHolder.getId(),video.getId());
                if (stringRedisTemplate.hasKey(key2)) {
                    videoVo.setHasLiked(1);//1表示已经点过赞
                }

                videoVoList.add(videoVo);
            }

        }
        pageBeanVo.setItems(videoVoList);
        return pageBeanVo;
    }


    /**
     * 发布小视频
     * @param videoThumbnail
     * @param videoFile
     */
    //@CacheEvict(value = "video",allEntries = true)
    public void saveVideo(MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {
        //1.保存封面     -oss
        String picUrl = "https://" + ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());
        //2.保存视频    -fastDFS
        StorePath storePath = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(), FileUtil.extName(videoFile.getOriginalFilename()), null);
        String videoUrl = webServer.getWebServerUrl() + storePath.getFullPath();//拼接文件路径
        System.out.println("----->" + videoUrl);
        //3.构建Video对象
        Video video = new Video();
        video.setUserId(UserHolder.getId());//当前登录用户
        video.setText("万水千山只等闲");
        video.setPicUrl(picUrl);//封面路径
        video.setVideoUrl(videoUrl);//视频路径
        //4.保存数据
        ObjectId videoId = videoService.saveVideo(video);

        //发送MQ操作
        mqVideoManager.sendVideoMsg(videoId.toHexString(), MQVideoManager.VIDEO_PUBLISH);
    }



    /**
     * 关注小视频用户
     * @param videoUserId
     */
    //@CacheEvict(value = "video",allEntries = true)
    public void saveUserFocus(Long videoUserId) {
        //构建对象
        FocusUser focusUser = new FocusUser();
        focusUser.setUserId(UserHolder.getId());
        focusUser.setFocusUserId(videoUserId);
        //直接保存
        focusUserService.saveUserFocus(focusUser);
        //存入缓存中
        //谁关注了我 99_2
        String key = StrUtil.format(ConstantUtil.FOCUS_USER, UserHolder.getId(), videoUserId);
        stringRedisTemplate.opsForValue().set(key,"1");
    }

    /**
     * 取消关注小视频用户
     * @param videoUserId
     */
    //@CacheEvict(value = "video",allEntries = true)
    public void deleteUserFocus(Long videoUserId) {
        //当前用户id
        Long loginUserId = UserHolder.getId();
        //删除记录
        focusUserService.deleteUserFocus(loginUserId, videoUserId);

        //删除缓存
        String key = StrUtil.format(ConstantUtil.FOCUS_USER, UserHolder.getId(), videoUserId);
        stringRedisTemplate.delete(key);

    }

    @Reference
    private CommentService commentService;
    /**
     *    视频点赞
     * @param videoId
     */
    //@CacheEvict(value = "video",allEntries = true)
    public void saveVideoLike(String videoId) {
        //Video video =videoService.findByVideoId(videoId);
        //1.构建comment对象
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(videoId));
        comment.setCommentType(4);//类型  对视频进行点赞操作
        comment.setUserId(UserHolder.getId());//当前登录用户为操作人
        //2.保存对象
        Integer count = commentService.saveVideoComment(comment);

        //3.将数据存入ridis缓存中    xx对哪个视屏进行了点赞操作 userId 视屏的id
        String key = StrUtil.format(ConstantUtil.VIDEO_LIKE, UserHolder.getId(),videoId);
        stringRedisTemplate.opsForValue().set(key,"4");
        //发送MQ操作
        mqVideoManager.sendVideoMsg(videoId, MQVideoManager.VIDEO_LIKE);
    }

    /**
     * 视频取消点赞
     * @param videoId
     */
    //@CacheEvict(value = "video",allEntries = true)
    public void deleteVideoLike(String videoId) {
        //1.构建comment对象
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(videoId));
        comment.setCommentType(4);//类型  对视频进行点赞操作
        comment.setUserId(UserHolder.getId());//当前登录用户为操作人
        //2.保存comment对象
        Integer count = commentService.deleteVideoLike(comment);
        //从缓存中删除点赞记录
        String key = StrUtil.format(ConstantUtil.VIDEO_LIKE, UserHolder.getId(),videoId);
        stringRedisTemplate.delete(key);
        //发送MQ操作
        mqVideoManager.sendVideoMsg(videoId, MQVideoManager.VIDEO_DISLIKE);
    }

    /**
     * 保存视频评论
     */
    public void saveVideoComment(String videoId, String content) {
        //1.构建comment对象
        Comment comment = new Comment();
        comment.setCommentType(5);
        comment.setUserId(UserHolder.getId());//操作人
        comment.setContent(content);//评论内容
        comment.setPublishId(new ObjectId(videoId));

        //2.调用service保存
        commentService.saveVideoComment(comment);
        //发送MQ操作
        mqVideoManager.sendVideoMsg(videoId, MQVideoManager.VIDEO_COMMENT);
    }

    /**
     * 查询视频评论列表
     */
    public PageBeanVo findVideoComment(Integer pageNum, Integer pageSize, String videoId) {
        //1.分页查询视屏评论
        PageBeanVo pageBeanVo = videoService.findVideoComment(pageNum, pageSize, videoId);
        //2.根据视屏的评论查询个人信息
        List<Comment> items = (List<Comment>) pageBeanVo.getItems();
        List<CommentVo> commentVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(items)) {
            for (Comment comment : items) {
                //3.封装CommentVo
                //查询个人信息
                UserInfo userInfo = userInfoService.findById(comment.getUserId());
                //创建对象
                CommentVo vo = new CommentVo();
                BeanUtil.copyProperties(userInfo, vo);
                BeanUtil.copyProperties(comment, vo);
                //处理时间字段
                vo.setCreateDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(comment.getCreated()));
                String key = StrUtil.format(ConstantUtil.VIDEO_COMMENT_LIKE, UserHolder.getId(),comment.getId());
                Boolean hasKey = stringRedisTemplate.hasKey(key);
                if (hasKey){
                   vo.setHasLiked(1);
               }
                commentVoList.add(vo);

            }
        }
        pageBeanVo.setItems(commentVoList);
        return pageBeanVo;
    }

    /**
     * 视频评论点赞
     * @param contentId
     */
    public void videoCommentLike(String contentId) {
        //1.构建comment对象
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(contentId));
        comment.setCommentType(6);//类型  对视频评论进行点赞操作
        comment.setUserId(UserHolder.getId());//当前登录用户为操作人
        //2.保存对象
        Integer count = commentService.videoCommentLike(comment);

        //3.将数据存入ridis缓存中    xx对哪个视屏进行了点赞操作 userId 视屏的id
        String key = StrUtil.format(ConstantUtil.VIDEO_COMMENT_LIKE, UserHolder.getId(),contentId);
        stringRedisTemplate.opsForValue().set(key,"1");

    }

    /**
     * 取消视频评论点赞
     * @param contentId
     */
    public void deleteVideoCommentLike(String contentId) {
        //1.构建comment对象
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(contentId));
        comment.setCommentType(6);//类型  对视频进行点赞操作
        comment.setUserId(UserHolder.getId());//当前登录用户为操作人
        //2.保存comment对象
        Integer count = commentService.deleteVideoCommentLike(comment);
        //从缓存中删除点赞记录
        String key = StrUtil.format(ConstantUtil.VIDEO_COMMENT_LIKE, UserHolder.getId(),contentId);
        stringRedisTemplate.delete(key);
    }
}
